package tool.soft

import java.io.File
import command.CommandExec
import dao._
import models.Tables
import org.joda.time.DateTime
import play.api.mvc.{AnyContent, Request}
import play.twirl.api.Html
import shared.Pojo._
import tool.Pojo._
import tool._
import tool.plot._
import tool.soft.AllSoft.SoftBT
import implicits.Implicits._
import models.Tables._
import play.api.data.FormBinding
import play.api.i18n.Messages

import scala.collection.immutable.SeqMap
import upickle.default._

/**
 * Created by yz on 15/9/2020
 */
object CcaRdaSoft extends CcaRdaSoftT with SoftBT {

 override def getFileInfos(workspaceDir: File, index: Int)(implicit matrixFileDataDao: MatrixFileDataDao, messages: Messages): List[FileInfoData] = {
    List(
      FileInfoData("percent.csv", messages("percent")),
      FileInfoData("samples.csv", messages("samples")),
      FileInfoData("species.csv", messages("species")),
      FileInfoData("envi.csv", messages("envi")),
      FileInfoData("rdacca.pdf", messages("rdacca")),
    )
  }

   override def produceConfigFile(workspaceDir: File,index:Int)(implicit request: Request[AnyContent], formBinding: FormBinding) = {
    val data = FormTool.ccaRdaForm.bindFromRequest().get
    data.lines().toTxtFile(Tool.getCalculateConfigTxtFile(workspaceDir))
    Tool.producePlotConfigFile(SFormTool.getAllPlotData, CcaRda, workspaceDir)
  }

  def getArg(implicit request: Request[AnyContent], messages: Messages, formBinding: FormBinding): ujson.Value = {
    val userId = Tool.getUserId
    val data = FormTool.ccaRdaForm.bindFromRequest().get
    val argMap = SeqMap(messages("analysisKind") -> data.analysisKind)
    writeJs(argMap)
  }

  override def getResultHtml(missionId: Int)(implicit request: Request[AnyContent], messages: Messages): Html = {
    views.html.user.mission.ccaRdaResult(missionId)
  }

   override def getCommandData(workspaceDir: File, resultDir: File, index: Int):  List[CommandData] = {
    val solutionFile = new File(Tool.dataDir, "color_solution/color_solution_1.txt")
    val groupFile = new File(workspaceDir, "group.txt")
    val command =
      s"""
         |${Tool.rScript} ${new File(Tool.rPath, "produce_sample_color.R").unixPath} --g ${groupFile.unixPath}  --solution ${solutionFile.unixPath}
         |${Tool.rScript} ${new File(Tool.rPath, "rda_cca_calculate.R").unixPath}
         |${Tool.rScript} ${new File(Tool.rPath, "rda_cca_plot.R").unixPath} --pc ${CcaRda.configFileName}
         |convert  -density 300 rdacca.pdf  rdacca.png
           """.stripMargin
     List(CommandData(workspaceDir, List(command)))
  }

  override def getHtml(missionName: String, missionId: Option[Int])(implicit request: Request[AnyContent], messages: Messages): Html = {
    views.html.user.soft.ccaRda(missionName, missionId)
  }

   override def getMission(implicit request: Request[AnyContent], matrixFileDataDao: MatrixFileDataDao, messages: Messages, formBinding: FormBinding): Tables.MissionRow = {
    val data = FormTool.ccaRdaForm.bindFromRequest().get
    val input = if (data.hasGroup.isDefined) {
      List(data.file, data.listFile, data.groupFile)
    } else List(data.file, data.listFile)
    val argJson = getArg
    MissionRow(id = 0, missionName = s"${data.missionName}", kind = nameStr, userId = userId,
      startTime = new DateTime(), state = "preparing", arg = argJson, input = input)
  }

  override def produceInputFile(workspaceDir: File)(implicit request: Request[AnyContent], dao: MyDao, formBinding: FormBinding): Any = {
    val userId = Tool.getUserId
    val rawDataFile = new File(workspaceDir, "AllMet_Raw.txt")
    Tool.produceRawDataFile(userId, data.file, rawDataFile)
    Tool.produceRawDataFile(userId, data.listFile, new File(workspaceDir, "list.txt"))
    val groupFile = new File(workspaceDir, "group.txt")
    if (data.hasGroup.isDefined) {
      Tool.produceRawGroupFile(userId, data.groupFile, groupFile)
    } else {
      Tool.produceNoGroupFile(rawDataFile, groupFile)
    }
  }

  override def data(implicit request: Request[AnyContent], formBinding: FormBinding) = {
    FormTool.ccaRdaForm.bindFromRequest().get
  }


}

